home *** CD-ROM | disk | FTP | other *** search
/ Network Support Library / RoseWare - Network Support Library.iso / apidev / batuti.arc / MST_ENV.C < prev    next >
Text File  |  1990-01-10  |  8KB  |  308 lines

  1. /*
  2.  *
  3.  *   st_env.c -- Accessing the MS_DOS Master Environment, The C Users
  4.  *               Journal, July 1989, page 59.
  5.  *
  6.  *
  7.  */
  8.  
  9. #include <dos.h>
  10. #include <stddef.h>
  11. #include <string.h>
  12. #include "mst_env.h"      /* prototypes */
  13.  
  14. /*
  15.  *       Internal Ms-Dos structures
  16.  */
  17.  
  18. typedef struct
  19. {
  20.    char reserved1[22] ;
  21.    unsigned par_seg ;        /* segment of the parent of the cureent program  */
  22.    char reserved2[20] ;
  23.    unsigned  env_seg ;
  24. }
  25. PSP ;
  26.  
  27. typedef struct
  28. {
  29.    char status ;             /* indicates wheter this block is in a chain */
  30.    unsigned owner_PSP ;      /* the PSP segment of this blocks owner */
  31.    unsigned len ;            /* the size (in paragraphs) of this memory block */
  32. }
  33. MCB ;
  34.  
  35. /*
  36.  *       Global declarations
  37.  *       ------ ------------
  38.  */
  39.  
  40. char far *env_ptr;           /* pointer to the first byte of global env. */
  41.  
  42. static unsigned env_len;     /* indicates whether the module is intialized */
  43.  
  44. static int initialized = 0 ; /* indicates wheter the module is initialized */
  45.  
  46. static char s[256] ;         /* internal buffer used for strings */
  47.  
  48. static void m_findenv(void) ;/* internal function used to find the master
  49.                                 environment */
  50.  
  51. #define NUL '\x00'           /* the nul (zero) charcter used by C as a string
  52.                                 terminator */
  53. /*
  54.  *       function definitions
  55.  *       -------- -----------
  56.  *
  57.  */
  58.  
  59.  
  60.  /*    function:   m_getenv
  61.   *
  62.   *    purpose:    retrives an environment variable's value
  63.   *    parameters: name -- the name of the varible whose value is sought
  64.   *
  65.   *    returns:    A pointer to the value of the requested variable , or NULL
  66.   *                if the variable was not found.
  67.   *
  68.   *                Note: the return value is a pointer to a static char array in
  69.   *                this module. Thus the previous value is destroyed each time
  70.   *                this function is called.
  71.   */
  72.  
  73.  char *m_getenv(char *name)
  74.  {
  75.     char far *e ;
  76.     char *n ;
  77.     int i ;
  78.  
  79.     /* check for initialization */
  80.     if (!initialized)
  81.        m_findenv() ;
  82.     e = env_ptr ;
  83.  
  84.     /* search for name */
  85.     while (*e)
  86.     {
  87.       n=name ;
  88.  
  89.       while ((*e == *n) && (*e != '=') && (*e != NUL) && (*n != NUL))
  90.       {
  91.          ++e ;
  92.          ++n ;
  93.       }
  94.  
  95.       if ((*n == NUL) && (*e == '='))   /* name found */
  96.       {
  97.          /* copy variable value to s */
  98.          ++e ;
  99.  
  100.          /* strcpy() cannot be used becuase pointer sizes may differ */
  101.          for (i=0 ; (i < 256) && (*e != NUL) ; ++i)
  102.          {
  103.             s[i]=*e ;
  104.             ++e ;
  105.          }
  106.  
  107.          if ( i<256 )
  108.             s[i] = NUL ;
  109.  
  110.          return s ;          /* contains value of name */
  111.       }
  112.  
  113.       /* skip to the next envirnoment varialbe */
  114.       while (*e != NUL)
  115.          ++e ;
  116.  
  117.       ++e ;
  118.       }
  119. /* name wasn't found */
  120. return NULL ;
  121. }
  122.  
  123. /*     function:   m_putenv
  124.  *
  125.  *     purpose:    stores an environment variable
  126.  *
  127.  *     parameters: name -- name of the variable to be stored
  128.  *                 text -- the variable's value
  129.  *
  130.  *     returns:    0 if the variable was stored
  131.  *                 1 if not
  132.  *
  133.  */
  134.  
  135. int m_putenv(char *name, char *text)
  136. {
  137.     char far *e ;
  138.     unsigned l = 0 ;
  139.     char *sptr ;
  140.  
  141.     /* check for initialization */
  142.     if (!initialized)
  143.        m_findenv() ;
  144.  
  145.     e = env_ptr ;
  146.  
  147.     /* check to see that the storage required is < 256 bytes */
  148.     if ((strlen(name) + 2 + strlen(text)) > 256)
  149.        return 1 ;
  150.  
  151.     /* make a complete environment string from the components given */
  152.     strcpy(s,name) ;
  153.     strupr(s) ;
  154.     strcat(s,"=") ;
  155.     strcat(s,text) ;
  156.  
  157.     /* delete any existing variables of the same name */
  158.     m_delenv(name) ;
  159.  
  160.     /* find the end of the current variables (mark by two nulls) */
  161.     e=env_ptr ;
  162.     l=0 ;
  163.  
  164.     /* loop until two NULs are found, signifying the end of the environment */
  165.     while (!((*e == NUL) && (*(e+1) == NUL)))
  166.     {
  167.        ++e ;
  168.        ++l ;
  169.      }
  170.  
  171.      /* get the amount of remaining space */
  172.      l=env_len - l - 1 ;
  173.  
  174.      /* if the new variable won't fit, return an error */
  175.      if (l<strlen(s))
  176.         return 1 ;
  177.  
  178.      sptr=s ;
  179.  
  180.      /* otherwise, copy s onto the end of the current environment */
  181.      ++e ;
  182.  
  183.      while (*sptr != NUL)
  184.         *e++=*sptr++;
  185.  
  186.      /* end the environment with two NUL bytes */
  187.      *e=NUL ;
  188.      *(e + 1) = NUL ;
  189.  
  190.      /* it worked */
  191.      return 0 ;
  192. }
  193.  
  194.  
  195. /*   function:    m_delenv
  196.  *
  197.  *   purpose:     deletes an environment variable
  198.  *
  199.  *   parameters:  name -- name of the environment variable to delete
  200.  *
  201.  *   returns:     1 if the variable could not be deleted or does not exist
  202.  *                0 successful deletion
  203.  */
  204.  
  205. int m_delenv(char *name)
  206. {
  207.    char far *e1 ;      /* used in search & marks beginning of next variable */
  208.    char far *e2 ;      /* marks beginning of the variable */
  209.    char *n ;           /* name pointer used in search */
  210.    int searching = 1 ; /* flag to indicate search end */
  211.  
  212.    /* check for initialization */
  213.    if (!initialized)
  214.       m_findenv() ;
  215.    e1=env_ptr ;
  216.  
  217.    /* find the beginning of the variable to be deleted */
  218.    while ((*e1 != NUL) && (searching))
  219.    {
  220.       n=name ;
  221.       e2=e1 ;
  222.  
  223.       while ((*e1 == *n) && (*e1 != '=') && (*e1 != NUL) && (*n != NUL))
  224.       {
  225.          ++e1 ;
  226.          ++n ;
  227.       }
  228.  
  229.       if ((!*n) && ( *e1 == '='))
  230.          searching=0 ; /* variable we want was found! */
  231.  
  232.       while (*e1 != NUL)
  233.          ++e1 ;
  234.  
  235.       ++e1 ;
  236.       }
  237.  
  238.    /* if name wasn't found , return an error */
  239.    if ((*e1 == NUL) && (searching))
  240.       return 1 ;
  241.  
  242.    /* otherwise, copy the remainder of the environment over the name */
  243.    while (!((*e1 == NUL) && (*(e1+1) == NUL)))
  244.    {
  245.       *e2=*e1 ;
  246.       *e2++ ;
  247.       *e1++ ;
  248.    }
  249.  
  250.    /* end the environment with two NUL bytes */
  251.    *e2=NUL ;
  252.    *(e2+1)=NUL ;
  253.  
  254.    /* return success code */
  255.    return 0 ;
  256. }
  257.  
  258.  
  259. /*   function:   m_findenv
  260.  *
  261.  *   purpose:    locates the global environment and sets a pointer to it
  262.  *
  263.  *   parameters: none
  264.  *
  265.  *   returns:    nothing
  266.  */
  267.  
  268. static void m_findenv(void)
  269. {
  270.    union REGS regs ;
  271.    struct SREGS sregs ;
  272.    int far *SEGptr ;      /* set to the address of segment of the first MCB */
  273.    MCB far *CONFIGmcb ;   /* set to the address of CONFIG's MCB */
  274.    MCB far *SHELLmcb ;    /* set to the address of COMMAND's MCB */
  275.    MCB far *ENVmcb ;      /* set to the address of Environment's MCB */
  276.    PSP far *SHELLpsp ;    /* set to the address of COMMAND's PSP */
  277.  
  278.    regs.h.ah=0x52 ;
  279.    intdosx(®s,®s,&sregs) ;
  280.  
  281.    SEGptr=MK_FP(sregs.es,regs.x.bx-2) ;
  282.  
  283.    CONFIGmcb=MK_FP(*SEGptr,0) ;
  284.  
  285.    SHELLpsp=MK_FP(FP_SEG(CONFIGmcb) + CONFIGmcb->len + 2,0) ;
  286.  
  287.    if (SHELLpsp->env_seg == 0)
  288.    {
  289.       /* the environment is in the block AFTER the parent process */
  290.       SHELLmcb=MK_FP(FP_SEG(CONFIGmcb) + CONFIGmcb->len + 1,0) ;
  291.       env_ptr=MK_FP(FP_SEG(SHELLmcb) + SHELLmcb->len +2,0) ;
  292.    }
  293.    else
  294.    {
  295.       /* otherwise we have a direct pointer to the environment block */
  296.       env_ptr=MK_FP(SHELLpsp->env_seg,0) ;
  297.    }
  298.  
  299.    /* set a pointer to the MCB of the environment block */
  300.    ENVmcb=MK_FP(FP_SEG(env_ptr) - 1,0) ;
  301.  
  302.    /* calculate thje length of the environment */
  303.    env_len=ENVmcb->len * 16 ;
  304.  
  305.    /* set the initialition flag */
  306.    initialized=1 ;
  307. }
  308.